/*      */ package com.zimbra.cs.mailbox.calendar;
/*      */ 
/*      */ import com.google.common.annotations.VisibleForTesting;
/*      */ import com.google.common.io.Closeables;
/*      */ import com.zimbra.common.account.Key.AccountBy;
/*      */ import com.zimbra.common.account.Key.SignatureBy;
/*      */ import com.zimbra.common.account.SignatureUtil;
/*      */ import com.zimbra.common.account.ZAttrProvisioning.PrefCalendarAllowedTargetsForInviteDeniedAutoReply;
/*      */ import com.zimbra.common.calendar.Attach;
/*      */ import com.zimbra.common.calendar.ICalTimeZone;
/*      */ import com.zimbra.common.calendar.ParsedDateTime;
/*      */ import com.zimbra.common.calendar.TimeZoneMap;
/*      */ import com.zimbra.common.calendar.ZCalendar.ICalTok;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZComponent;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZProperty;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZVCalendar;
/*      */ import com.zimbra.common.localconfig.DebugConfig;
/*      */ import com.zimbra.common.mime.ContentDisposition;
/*      */ import com.zimbra.common.mime.shim.JavaMailInternetAddress;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.util.L10nUtil;
/*      */ import com.zimbra.common.util.L10nUtil.MsgKey;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.common.zmime.ZMimeBodyPart;
/*      */ import com.zimbra.common.zmime.ZMimeMessage;
/*      */ import com.zimbra.common.zmime.ZMimeMultipart;
/*      */ import com.zimbra.cs.account.Account;
/*      */ import com.zimbra.cs.account.CalendarResource;
/*      */ import com.zimbra.cs.account.Identity;
/*      */ import com.zimbra.cs.account.Provisioning;
/*      */ import com.zimbra.cs.account.Signature;
/*      */ import com.zimbra.cs.mailbox.CalendarItem;
/*      */ import com.zimbra.cs.mailbox.MailSender;
/*      */ import com.zimbra.cs.mailbox.MailServiceException;
/*      */ import com.zimbra.cs.mailbox.Mailbox;
/*      */ import com.zimbra.cs.mailbox.OperationContext;
/*      */ import com.zimbra.cs.mime.Mime.FixedMimeMessage;
/*      */ import com.zimbra.cs.mime.MimeVisitor;
/*      */ import com.zimbra.cs.mime.MimeVisitor.VisitPhase;
/*      */ import com.zimbra.cs.redolog.RedoLogManager;
/*      */ import com.zimbra.cs.redolog.RedoLogProvider;
/*      */ import com.zimbra.cs.redolog.op.RedoableOp;
/*      */ import com.zimbra.cs.service.FileUploadServlet.Upload;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import com.zimbra.cs.util.AccountUtil;
/*      */ import com.zimbra.cs.util.JMSession;
/*      */ import com.zimbra.cs.util.Zimbra;
/*      */ import java.io.ByteArrayInputStream;
/*      */ import java.io.ByteArrayOutputStream;
/*      */ import java.io.IOException;
/*      */ import java.io.InputStream;
/*      */ import java.io.OutputStream;
/*      */ import java.io.OutputStreamWriter;
/*      */ import java.io.StringWriter;
/*      */ import java.text.SimpleDateFormat;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Date;
/*      */ import java.util.Enumeration;
/*      */ import java.util.HashMap;
/*      */ import java.util.Iterator;
/*      */ import java.util.List;
/*      */ import java.util.Locale;
/*      */ import java.util.Map;
/*      */ import java.util.TimeZone;
/*      */ import javax.activation.DataHandler;
/*      */ import javax.activation.DataSource;
/*      */ import javax.mail.Address;
/*      */ import javax.mail.Header;
/*      */ import javax.mail.Message.RecipientType;
/*      */ import javax.mail.MessagingException;
/*      */ import javax.mail.Part;
/*      */ import javax.mail.internet.AddressException;
/*      */ import javax.mail.internet.ContentType;
/*      */ import javax.mail.internet.InternetAddress;
/*      */ import javax.mail.internet.MimeBodyPart;
/*      */ import javax.mail.internet.MimeMessage;
/*      */ import javax.mail.internet.MimeMultipart;
/*      */ import javax.mail.util.ByteArrayDataSource;
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ public class CalendarMailSender
/*      */ {
/*      */   public static final String X_ZIMBRA_CALENDAR_INTENDED_FOR = "X-Zimbra-Calendar-Intended-For";
/*      */   public static final Verb VERB_ACCEPT;
/*      */   public static final Verb VERB_DECLINE;
/*      */   public static final Verb VERB_TENTATIVE;
/*      */   protected static Map<String, Verb> sVerbs;
/*      */   private static Map<Verb, L10nUtil.MsgKey> sVerbMsgKeys;
/*      */   
/*      */   public static MailSender getCalendarMailSender(Mailbox mbox)
/*      */     throws ServiceException
/*      */   {
/*  109 */     MailSender sender = mbox.getMailSender();
/*  110 */     sender.setCalendarMode(true);
/*  111 */     return sender;
/*      */   }
/*      */   
/*      */   public static final class Verb
/*      */   {
/*      */     String mName;
/*      */     String mPartStat;
/*      */     
/*      */     public Verb(String name, String xmlPartStat)
/*      */     {
/*  121 */       this.mName = name;
/*  122 */       this.mPartStat = xmlPartStat;
/*      */     }
/*      */     
/*  125 */     public String toString() { return this.mName; }
/*  126 */     public String getXmlPartStat() { return this.mPartStat; }
/*      */   }
/*      */   
/*  129 */   static { VERB_ACCEPT = new Verb("ACCEPT", "AC");
/*  130 */     VERB_DECLINE = new Verb("DECLINE", "DE");
/*  131 */     VERB_TENTATIVE = new Verb("TENTATIVE", "TE");
/*      */     
/*      */ 
/*      */ 
/*  135 */     sVerbs = new HashMap();
/*  136 */     sVerbs.put("accept", VERB_ACCEPT);
/*  137 */     sVerbs.put("decline", VERB_DECLINE);
/*  138 */     sVerbs.put("tentative", VERB_TENTATIVE);
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*  143 */     sVerbMsgKeys = new HashMap();
/*  144 */     sVerbMsgKeys.put(VERB_ACCEPT, L10nUtil.MsgKey.calendarReplySubjectAccept);
/*  145 */     sVerbMsgKeys.put(VERB_DECLINE, L10nUtil.MsgKey.calendarReplySubjectDecline);
/*  146 */     sVerbMsgKeys.put(VERB_TENTATIVE, L10nUtil.MsgKey.calendarReplySubjectTentative);
/*      */   }
/*      */   
/*      */   public static Verb parseVerb(String str) throws ServiceException {
/*  150 */     Verb verb = (Verb)sVerbs.get(str.toLowerCase());
/*  151 */     if (verb != null)
/*  152 */       return verb;
/*  153 */     throw ServiceException.INVALID_REQUEST("Unknown Reply Verb: " + str, null);
/*      */   }
/*      */   
/*      */   public static String getReplySubject(Verb verb, String subject, Locale lc)
/*      */   {
/*  158 */     L10nUtil.MsgKey key = (L10nUtil.MsgKey)sVerbMsgKeys.get(verb);
/*  159 */     String prefix = L10nUtil.getMessage(key, lc, new Object[0]);
/*  160 */     return prefix + ": " + subject;
/*      */   }
/*      */   
/*      */   public static String getCancelSubject(String subject, Locale lc) {
/*  164 */     String prefix = L10nUtil.getMessage(L10nUtil.MsgKey.calendarSubjectCancelled, lc, new Object[0]) + ": ";
/*  165 */     if ((subject != null) && (subject.startsWith(prefix))) {
/*  166 */       return subject;
/*      */     }
/*  168 */     return prefix + subject;
/*      */   }
/*      */   
/*      */   public static MimeMessage createOrganizerChangeMessage(Account fromAccount, Account authAccount, boolean asAdmin, CalendarItem calItem, Invite inv, List<Address> rcpts)
/*      */     throws ServiceException
/*      */   {
/*  174 */     ZOrganizer organizer = inv.getOrganizer();
/*  175 */     assert (organizer != null);
/*  176 */     boolean onBehalfOf = organizer.hasSentBy();
/*  177 */     String senderAddr = onBehalfOf ? organizer.getSentBy() : organizer.getAddress();
/*      */     
/*  179 */     Locale locale = fromAccount.getLocale();
/*      */     
/*  181 */     boolean hidePrivate = (!calItem.isPublic()) && (!calItem.allowPrivateAccess(authAccount, asAdmin));
/*      */     String subject;
/*  183 */     String subject; if (hidePrivate) {
/*  184 */       subject = L10nUtil.getMessage(L10nUtil.MsgKey.calendarSubjectWithheld, locale, new Object[0]);
/*      */     } else {
/*  186 */       subject = inv.getName();
/*      */     }
/*  188 */     StringBuilder sb = new StringBuilder("Organizer has been changed to " + fromAccount.getName());
/*  189 */     sb.append("\r\n\r\n");
/*      */     
/*  191 */     if (!hidePrivate) {
/*  192 */       MimeMessage mmInv = inv.getMimeMessage();
/*  193 */       if (mmInv != null) {
/*  194 */         attachInviteSummary(sb, inv, mmInv, locale);
/*      */       }
/*      */     }
/*      */     
/*  198 */     ZCalendar.ZVCalendar iCal = inv.newToICalendar(true);
/*      */     
/*  200 */     Address from = AccountUtil.getFriendlyEmailAddress(fromAccount);
/*  201 */     Address sender = null;
/*  202 */     if (onBehalfOf) {
/*      */       try {
/*  204 */         sender = new JavaMailInternetAddress(senderAddr);
/*      */       } catch (AddressException e) {
/*  206 */         throw MailServiceException.ADDRESS_PARSE_ERROR(e);
/*      */       }
/*      */     }
/*  209 */     return createCalendarMessage(authAccount, from, sender, rcpts, subject, sb.toString(), null, inv.getUid(), iCal);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static MimeMessage createDefaultReply(Account fromAccount, String fromIdentityId, Account authAccount, String authIdentityId, boolean asAdmin, boolean onBehalfOf, CalendarItem calItem, Invite inv, MimeMessage mmInv, String replySubject, Verb verb, String additionalMsgBody, ZCalendar.ZVCalendar iCal)
/*      */     throws ServiceException
/*      */   {
/*  219 */     return createDefaultReply(fromAccount, fromIdentityId, authAccount, authIdentityId, asAdmin, onBehalfOf, calItem, inv, mmInv, replySubject, verb, false, additionalMsgBody, iCal, false);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static MimeMessage createDefaultReply(Account fromAccount, String fromIdentityId, Account authAccount, String authIdentityId, boolean asAdmin, boolean onBehalfOf, CalendarItem calItem, Invite inv, MimeMessage mmInv, String replySubject, Verb verb, boolean partialAccept, String additionalMsgBody, ZCalendar.ZVCalendar iCal, boolean addSignature)
/*      */     throws ServiceException
/*      */   {
/*  233 */     Identity fromIdentity = null;
/*  234 */     if (fromIdentityId != null) {
/*  235 */       fromIdentity = fromAccount.getIdentityById(fromIdentityId);
/*  236 */       if (fromIdentity == null) {
/*  237 */         ZimbraLog.calendar.warn("No such identity " + fromIdentityId + " for account " + fromAccount.getName());
/*  238 */         fromIdentity = getTargetedIdentity(fromAccount, inv);
/*      */       }
/*      */     } else {
/*  241 */       fromIdentity = getTargetedIdentity(fromAccount, inv);
/*      */     }
/*  243 */     Identity authIdentity = null;
/*  244 */     if (authIdentityId != null) {
/*  245 */       authIdentity = authAccount.getIdentityById(authIdentityId);
/*  246 */       if (authIdentity == null) {
/*  247 */         ZimbraLog.calendar.warn("No such identity " + authIdentityId + " for account " + authAccount.getName());
/*  248 */         if (authAccount.equals(fromAccount)) {
/*  249 */           authIdentity = fromIdentity;
/*      */         } else {
/*  251 */           authIdentity = getTargetedIdentity(authAccount, inv);
/*      */         }
/*      */       }
/*  254 */     } else if (authAccount.equals(fromAccount)) {
/*  255 */       authIdentity = fromIdentity;
/*      */     } else {
/*  257 */       authIdentity = getTargetedIdentity(authAccount, inv);
/*      */     }
/*      */     Locale lc;
/*      */     InternetAddress organizerAddress;
/*      */     Locale lc;
/*  262 */     if (inv.hasOrganizer()) {
/*  263 */       ZOrganizer org = inv.getOrganizer();
/*  264 */       InternetAddress organizerAddress = org.getReplyAddress();
/*  265 */       Account organizer = Provisioning.getInstance().get(Key.AccountBy.name, organizerAddress.getAddress());
/*  266 */       lc = organizer != null ? organizer.getLocale() : authAccount.getLocale();
/*      */     } else {
/*  268 */       organizerAddress = null;
/*  269 */       lc = authAccount.getLocale();
/*      */     }
/*      */     
/*  272 */     String fromDisplayName = fromIdentity.getAttr("zimbraPrefFromDisplay");
/*  273 */     if (fromDisplayName == null) {
/*  274 */       fromDisplayName = fromAccount.getAttr("displayName", fromAccount.getName());
/*      */     }
/*  276 */     StringBuilder replyText = new StringBuilder();
/*  277 */     boolean isResourceAccount = fromAccount instanceof CalendarResource;
/*      */     L10nUtil.MsgKey statusMsgKey;
/*      */     L10nUtil.MsgKey statusMsgKey;
/*  280 */     if (VERB_ACCEPT.equals(verb)) { L10nUtil.MsgKey statusMsgKey;
/*  281 */       if (isResourceAccount) { L10nUtil.MsgKey statusMsgKey;
/*  282 */         if (partialAccept) {
/*  283 */           statusMsgKey = L10nUtil.MsgKey.calendarResourceDefaultReplyPartiallyAccept;
/*      */         } else
/*  285 */           statusMsgKey = L10nUtil.MsgKey.calendarResourceDefaultReplyAccept;
/*      */       } else {
/*  287 */         statusMsgKey = L10nUtil.MsgKey.calendarDefaultReplyAccept;
/*      */       } } else { L10nUtil.MsgKey statusMsgKey;
/*  289 */       if (VERB_DECLINE.equals(verb)) { L10nUtil.MsgKey statusMsgKey;
/*  290 */         if (isResourceAccount) { L10nUtil.MsgKey statusMsgKey;
/*  291 */           if (partialAccept) {
/*  292 */             statusMsgKey = L10nUtil.MsgKey.calendarResourceDefaultReplyPartiallyDecline;
/*      */           } else
/*  294 */             statusMsgKey = L10nUtil.MsgKey.calendarResourceDefaultReplyDecline;
/*      */         } else {
/*  296 */           statusMsgKey = L10nUtil.MsgKey.calendarDefaultReplyDecline;
/*      */         } } else { L10nUtil.MsgKey statusMsgKey;
/*  298 */         if (VERB_TENTATIVE.equals(verb)) { L10nUtil.MsgKey statusMsgKey;
/*  299 */           if (isResourceAccount) {
/*  300 */             statusMsgKey = L10nUtil.MsgKey.calendarResourceDefaultReplyTentativelyAccept;
/*      */           } else
/*  302 */             statusMsgKey = L10nUtil.MsgKey.calendarDefaultReplyTentativelyAccept;
/*      */         } else {
/*  304 */           statusMsgKey = L10nUtil.MsgKey.calendarDefaultReplyOther;
/*      */         } } }
/*      */     String statusMsg;
/*      */     String statusMsg;
/*  308 */     if (!statusMsgKey.equals(L10nUtil.MsgKey.calendarDefaultReplyOther)) {
/*  309 */       statusMsg = L10nUtil.getMessage(statusMsgKey, lc, new Object[] { fromDisplayName });
/*      */     } else
/*  311 */       statusMsg = L10nUtil.getMessage(statusMsgKey, lc, new Object[] { fromDisplayName, verb.toString() });
/*  312 */     replyText.append(statusMsg).append("\r\n\r\n");
/*      */     
/*  314 */     if (additionalMsgBody != null) {
/*  315 */       replyText.append(additionalMsgBody).append("\r\n");
/*      */     }
/*      */     
/*      */ 
/*  319 */     boolean sigAboveOriginal = true;
/*  320 */     String sigText = null;
/*  321 */     if (addSignature) {
/*  322 */       String sigStyle = fromAccount.getAttr("zimbraPrefMailSignatureStyle", "outlook");
/*  323 */       sigAboveOriginal = sigStyle.equalsIgnoreCase("outlook");
/*      */       String sigKey;
/*  325 */       String sigKey; if (VERB_DECLINE.equals(verb)) {
/*  326 */         sigKey = "zimbraPrefCalendarAutoDeclineSignatureId";
/*      */       } else
/*  328 */         sigKey = "zimbraPrefCalendarAutoAcceptSignatureId";
/*  329 */       sigText = getSignatureText(fromAccount, fromIdentity, sigKey);
/*  330 */       if ((sigAboveOriginal) && (sigText != null) && (sigText.length() > 0)) {
/*  331 */         replyText.append(sigText).append("\r\n");
/*      */       }
/*      */     }
/*      */     
/*  335 */     boolean allowPrivateAccess = calItem != null ? calItem.allowPrivateAccess(authAccount, asAdmin) : true;
/*  336 */     if ((inv.isPublic()) || (allowPrivateAccess)) {
/*  337 */       attachInviteSummary(replyText, inv, mmInv, lc);
/*      */     }
/*      */     
/*  340 */     if ((addSignature) && (!sigAboveOriginal) && (sigText != null) && (sigText.length() > 0)) {
/*  341 */       replyText.append("\r\n-------------------------\r\n\r\n");
/*  342 */       replyText.append(sigText).append("\r\n");
/*      */     }
/*      */     
/*  345 */     List<Address> toList = new ArrayList(1);
/*  346 */     if (organizerAddress != null)
/*  347 */       toList.add(organizerAddress);
/*  348 */     Address senderAddr = null;
/*  349 */     if (onBehalfOf)
/*  350 */       senderAddr = authIdentity.getFriendlyEmailAddress();
/*  351 */     return createCalendarMessage(authAccount, fromIdentity.getFriendlyEmailAddress(), senderAddr, toList, replySubject, replyText.toString(), null, inv.getUid(), iCal);
/*      */   }
/*      */   
/*      */   private static void attachInviteSummary(StringBuilder sb, Invite inv, MimeMessage mmInv, Locale lc)
/*      */     throws ServiceException
/*      */   {
/*  357 */     String notes = inv.getDescription();
/*  358 */     if (((notes == null) || (notes.length() < 1)) && (mmInv != null))
/*  359 */       notes = Invite.getDescription(mmInv, "text/plain");
/*  360 */     if ((notes != null) && (notes.length() > 0))
/*      */     {
/*      */ 
/*      */ 
/*  364 */       notes = notes.replaceAll("[\\r\\n]+[\\*~]+[\\r\\n]+", "\r\n\r\n ~ ~ ~ ~ ~ ~ ~ ~ ~\r\n\r\n");
/*      */       
/*  366 */       sb.append("\r\n-----");
/*  367 */       sb.append(L10nUtil.getMessage(L10nUtil.MsgKey.calendarResourceReplyOriginalInviteSeparatorLabel, lc, new Object[0]));
/*      */       
/*  369 */       sb.append("-----\r\n\r\n");
/*  370 */       sb.append(notes);
/*  371 */       sb.append("\r\n\r\n");
/*      */     }
/*      */   }
/*      */   
/*      */   public static String formatDateTime(Date d, TimeZone tz, Locale lc) {
/*  376 */     String dateTimeFmt = L10nUtil.getMessage(L10nUtil.MsgKey.calendarResourceConflictDateTimeFormat, lc, new Object[0]);
/*      */     
/*  378 */     SimpleDateFormat dateTimeFormat = new SimpleDateFormat(dateTimeFmt, lc);
/*  379 */     dateTimeFormat.setTimeZone(tz);
/*  380 */     return dateTimeFormat.format(d);
/*      */   }
/*      */   
/*      */   public static String formatTime(Date t, TimeZone tz, Locale lc) {
/*  384 */     String timeOnlyFmt = L10nUtil.getMessage(L10nUtil.MsgKey.calendarResourceConflictTimeOnlyFormat, lc, new Object[0]);
/*      */     
/*  386 */     SimpleDateFormat timeFormat = new SimpleDateFormat(timeOnlyFmt, lc);
/*  387 */     timeFormat.setTimeZone(tz);
/*  388 */     return timeFormat.format(t);
/*      */   }
/*      */   
/*      */   public static String formatDate(Date t, TimeZone tz, Locale lc) {
/*  392 */     String dateOnlyFmt = L10nUtil.getMessage(L10nUtil.MsgKey.calendarResourceConflictDateOnlyFormat, lc, new Object[0]);
/*      */     
/*  394 */     SimpleDateFormat timeFormat = new SimpleDateFormat(dateOnlyFmt, lc);
/*  395 */     timeFormat.setTimeZone(tz);
/*  396 */     return timeFormat.format(t);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static List<Address> toListFromAttendees(List<ZAttendee> list)
/*      */     throws MailServiceException
/*      */   {
/*  408 */     List<Address> toList = new ArrayList(list.size());
/*  409 */     for (ZAttendee attendee : list) {
/*  410 */       toList.add(attendee.getFriendlyAddress());
/*      */     }
/*  412 */     return toList;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static MimeMessage createCancelMessage(Account fromAccount, Account senderAccount, boolean asAdmin, boolean onBehalfOf, List<Address> toAddrs, CalendarItem calItem, Invite inv, String text, ZCalendar.ZVCalendar iCal)
/*      */     throws ServiceException
/*      */   {
/*  420 */     Locale locale = !onBehalfOf ? fromAccount.getLocale() : senderAccount.getLocale();
/*  421 */     Invite defaultInv = calItem.getDefaultInviteOrNull();
/*      */     
/*  423 */     boolean hidePrivate = (!calItem.isPublic()) && (!calItem.allowPrivateAccess(senderAccount, asAdmin));
/*      */     String invSubject;
/*  425 */     String invSubject; if (hidePrivate) {
/*  426 */       invSubject = L10nUtil.getMessage(L10nUtil.MsgKey.calendarSubjectWithheld, locale, new Object[0]);
/*      */     } else
/*  428 */       invSubject = inv != null ? inv.getName() : "";
/*  429 */     String sbj = getCancelSubject(invSubject, locale);
/*  430 */     StringBuilder sb = new StringBuilder(text);
/*  431 */     sb.append("\r\n\r\n");
/*      */     
/*  433 */     if ((!inv.equals(defaultInv)) && (inv.getStartTime() != null) && (inv.getRecurId() != null)) {
/*  434 */       sb.append(L10nUtil.getMessage(L10nUtil.MsgKey.calendarCancelAppointmentInstanceWhich, locale, new Object[0]));
/*  435 */       sb.append(" ");
/*  436 */       ParsedDateTime start = inv.getStartTime();
/*  437 */       TimeZone tz = start.getTimeZone();
/*  438 */       Date startDate = new Date(start.getUtcTime());
/*  439 */       sb.append(formatDateTime(startDate, tz, locale));
/*  440 */       sb.append("\r\n\r\n");
/*      */     }
/*      */     
/*  443 */     if (!hidePrivate) {
/*  444 */       MimeMessage mmInv = inv.getMimeMessage();
/*  445 */       if ((mmInv == null) && (defaultInv != null))
/*  446 */         mmInv = defaultInv.getMimeMessage();
/*  447 */       if (mmInv != null) {
/*  448 */         attachInviteSummary(sb, inv, mmInv, locale);
/*      */       }
/*      */     }
/*  451 */     Address from = AccountUtil.getFriendlyEmailAddress(fromAccount);
/*  452 */     Address sender = null;
/*  453 */     if (onBehalfOf) {
/*  454 */       sender = AccountUtil.getFriendlyEmailAddress(senderAccount);
/*      */     }
/*  456 */     return createCalendarMessage(senderAccount, from, sender, toAddrs, sbj, sb.toString(), null, defaultInv != null ? defaultInv.getUid() : "unknown", iCal);
/*      */   }
/*      */   
/*      */ 
/*      */   public static MimeMessage createCalendarMessage(Invite inv)
/*      */     throws ServiceException
/*      */   {
/*  463 */     String subject = inv.getName();
/*  464 */     String desc = inv.getDescription();
/*  465 */     String descHtml = inv.getDescriptionHtml();
/*  466 */     String uid = inv.getUid();
/*  467 */     ZCalendar.ZVCalendar cal = inv.newToICalendar(true);
/*  468 */     return createCalendarMessage(null, null, null, null, subject, desc, descHtml, uid, cal, inv.getIcalendarAttaches(), true);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal)
/*      */     throws ServiceException
/*      */   {
/*  477 */     return createCalendarMessage(account, fromAddr, senderAddr, toAddrs, subject, desc, descHtml, uid, cal, true);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal, boolean replyToSender)
/*      */     throws ServiceException
/*      */   {
/*  485 */     return createCalendarMessage(account, fromAddr, senderAddr, toAddrs, subject, desc, descHtml, uid, cal, (List)null, replyToSender);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal, List<Attach> attaches, boolean replyToSender)
/*      */     throws ServiceException
/*      */   {
/*  494 */     if (desc == null)
/*  495 */       desc = "";
/*      */     try {
/*  497 */       MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
/*  498 */       MimeMultipart mpAlternatives = new ZMimeMultipart("alternative");
/*      */       MimeMultipart mpMixed;
/*  500 */       if ((attaches != null) && (!attaches.isEmpty())) {
/*  501 */         mpMixed = new ZMimeMultipart("mixed");
/*  502 */         mm.setContent(mpMixed);
/*  503 */         MimeBodyPart mbpWrapper = new ZMimeBodyPart();
/*  504 */         mbpWrapper.setContent(mpAlternatives);
/*  505 */         mpMixed.addBodyPart(mbpWrapper);
/*  506 */         for (Attach attach : attaches) {
/*  507 */           byte[] rawData = attach.getDecodedData();
/*  508 */           if (rawData != null)
/*      */           {
/*      */ 
/*  511 */             ContentDisposition cdisp = new ContentDisposition("attachment", true);
/*  512 */             String ctypeAsString = attach.getContentType();
/*  513 */             if (ctypeAsString == null) {
/*  514 */               ctypeAsString = "application/octet-stream";
/*      */             }
/*  516 */             ContentType ctype = new ContentType(ctypeAsString);
/*  517 */             if (attach.getFileName() != null) {
/*  518 */               ctype.setParameter("name", attach.getFileName());
/*  519 */               cdisp.setParameter("filename", attach.getFileName());
/*      */             }
/*  521 */             MimeBodyPart mbp2 = new ZMimeBodyPart();
/*  522 */             ByteArrayDataSource bads = new ByteArrayDataSource(rawData, ctypeAsString);
/*  523 */             mbp2.setDataHandler(new DataHandler(bads));
/*  524 */             mbp2.setHeader("Content-Type", ctype.toString());
/*  525 */             mbp2.setHeader("Content-Disposition", cdisp.toString());
/*  526 */             mbp2.setHeader("Content-Transfer-Encoding", "base64");
/*  527 */             mpMixed.addBodyPart(mbp2);
/*      */           }
/*      */         }
/*  530 */       } else { mm.setContent(mpAlternatives);
/*      */       }
/*      */       
/*      */ 
/*      */ 
/*      */ 
/*  536 */       cal.addDescription(desc, null);
/*      */       
/*      */ 
/*      */ 
/*  540 */       MimeBodyPart textPart = new ZMimeBodyPart();
/*  541 */       textPart.setText(desc, "utf-8");
/*  542 */       mpAlternatives.addBodyPart(textPart);
/*      */       
/*      */ 
/*      */ 
/*  546 */       MimeBodyPart htmlPart = new ZMimeBodyPart();
/*  547 */       if (descHtml != null) {
/*  548 */         ContentType ct = new ContentType("text/html");
/*  549 */         ct.setParameter("charset", "utf-8");
/*  550 */         htmlPart.setText(descHtml, "utf-8");
/*  551 */         htmlPart.setHeader("Content-Type", ct.toString());
/*      */       } else {
/*  553 */         htmlPart.setDataHandler(new DataHandler(new HtmlPartDataSource(desc)));
/*      */       }
/*  555 */       mpAlternatives.addBodyPart(htmlPart);
/*      */       
/*      */ 
/*      */ 
/*  559 */       MimeBodyPart icalPart = makeICalIntoMimePart(cal);
/*  560 */       mpAlternatives.addBodyPart(icalPart);
/*      */       
/*      */ 
/*      */ 
/*  564 */       if (subject != null) {
/*  565 */         mm.setSubject(subject, "utf-8");
/*      */       }
/*      */       
/*  568 */       if (toAddrs != null) {
/*  569 */         Address[] addrs = new Address[toAddrs.size()];
/*  570 */         toAddrs.toArray(addrs);
/*  571 */         mm.addRecipients(Message.RecipientType.TO, addrs);
/*      */       }
/*  573 */       if (fromAddr != null)
/*  574 */         mm.setFrom(fromAddr);
/*  575 */       if (senderAddr != null) {
/*  576 */         mm.setSender(senderAddr);
/*  577 */         if (replyToSender) {
/*  578 */           mm.setReplyTo(new Address[] { senderAddr });
/*      */         }
/*      */       }
/*  581 */       mm.setSentDate(new Date());
/*  582 */       mm.saveChanges();
/*  583 */       return mm;
/*      */     } catch (MessagingException e) {
/*  585 */       throw ServiceException.FAILURE("Messaging Exception while building MimeMessage from invite", e);
/*      */     }
/*      */   }
/*      */   
/*      */   private static class CalendarPartReplacingVisitor extends MimeVisitor
/*      */   {
/*      */     private final String mUid;
/*      */     private final ZCalendar.ZVCalendar mCal;
/*      */     private boolean mReplaced;
/*      */     private MimeBodyPart mCalendarPart;
/*      */     
/*      */     public CalendarPartReplacingVisitor(String uid, ZCalendar.ZVCalendar cal) {
/*  597 */       this.mUid = uid;
/*  598 */       this.mCal = cal;
/*      */     }
/*      */     
/*      */     private static boolean isCalendarPart(Part part) throws MessagingException {
/*  602 */       String mmCtStr = part.getContentType();
/*  603 */       if (mmCtStr != null) {
/*  604 */         ContentType mmCt = new ContentType(mmCtStr);
/*  605 */         return mmCt.match("text/calendar");
/*      */       }
/*  607 */       return false;
/*      */     }
/*      */     
/*      */     protected boolean visitBodyPart(MimeBodyPart bp)
/*      */       throws MessagingException
/*      */     {
/*  613 */       if ((this.mCalendarPart == null) && (isCalendarPart(bp)))
/*  614 */         this.mCalendarPart = bp;
/*  615 */       return false;
/*      */     }
/*      */     
/*      */     protected boolean visitMessage(MimeMessage mm, MimeVisitor.VisitPhase visitKind) throws MessagingException
/*      */     {
/*  620 */       if (MimeVisitor.VisitPhase.VISIT_END.equals(visitKind)) {
/*  621 */         if (!this.mReplaced)
/*      */         {
/*      */ 
/*  624 */           CalendarMailSender.setCalendarContent(mm, this.mCal);
/*      */         }
/*  626 */         return true;
/*      */       }
/*  628 */       return false;
/*      */     }
/*      */     
/*      */     protected boolean visitMultipart(MimeMultipart mp, MimeVisitor.VisitPhase visitKind)
/*      */       throws MessagingException
/*      */     {
/*  634 */       if ((MimeVisitor.VisitPhase.VISIT_END.equals(visitKind)) && 
/*  635 */         (!this.mReplaced) && (this.mCalendarPart != null))
/*      */       {
/*      */ 
/*  638 */         if (mp.removeBodyPart(this.mCalendarPart)) {
/*  639 */           MimeBodyPart newCalendarPart = new ZMimeBodyPart();
/*  640 */           CalendarMailSender.setCalendarContent(newCalendarPart, this.mCal);
/*  641 */           mp.addBodyPart(newCalendarPart);
/*  642 */           this.mReplaced = true;
/*  643 */           return true;
/*      */         }
/*  645 */         throw new MessagingException("Unable to remove old calendar part");
/*      */       }
/*      */       
/*      */ 
/*  649 */       return false;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, MimeMessage srcMm, Invite inv, ZCalendar.ZVCalendar cal, boolean replyToSender)
/*      */     throws ServiceException
/*      */   {
/*      */     try
/*      */     {
/*  659 */       String uid = inv.getUid();
/*  660 */       if (srcMm != null) {
/*  661 */         MimeMessage mm = new ZMimeMessage(srcMm);
/*      */         
/*  663 */         Enumeration eh = srcMm.getAllHeaders();
/*  664 */         while (eh.hasMoreElements()) {
/*  665 */           Header hdr = (Header)eh.nextElement();
/*  666 */           String hdrNameUpper = hdr.getName().toUpperCase();
/*  667 */           if ((!hdrNameUpper.startsWith("CONTENT-")) && (!hdrNameUpper.equals("SUBJECT"))) {
/*  668 */             mm.removeHeader(hdr.getName());
/*      */           }
/*      */         }
/*      */         
/*  672 */         mm.setSentDate(new Date());
/*      */         
/*  674 */         if (toAddrs != null) {
/*  675 */           Address[] addrs = new Address[toAddrs.size()];
/*  676 */           toAddrs.toArray(addrs);
/*  677 */           mm.setRecipients(Message.RecipientType.TO, addrs);
/*      */         } else {
/*  679 */           mm.setRecipients(Message.RecipientType.TO, (Address[])null);
/*      */         }
/*  681 */         mm.setRecipients(Message.RecipientType.CC, (Address[])null);
/*  682 */         mm.setRecipients(Message.RecipientType.BCC, (Address[])null);
/*      */         
/*  684 */         if (fromAddr != null)
/*  685 */           mm.setFrom(fromAddr);
/*  686 */         if (senderAddr != null) {
/*  687 */           mm.setSender(senderAddr);
/*  688 */           if (replyToSender) {
/*  689 */             mm.setReplyTo(new Address[] { senderAddr });
/*      */           }
/*      */         }
/*      */         
/*  693 */         CalendarPartReplacingVisitor visitor = new CalendarPartReplacingVisitor(uid, cal);
/*  694 */         visitor.accept(mm);
/*      */         
/*  696 */         mm.saveChanges();
/*  697 */         return mm;
/*      */       }
/*  699 */       String subject = inv.getName();
/*  700 */       String desc = inv.getDescription();
/*  701 */       String descHtml = inv.getDescriptionHtml();
/*  702 */       return createCalendarMessage(account, fromAddr, senderAddr, toAddrs, subject, desc, descHtml, uid, cal, false);
/*      */     }
/*      */     catch (MessagingException e) {
/*  705 */       throw ServiceException.FAILURE("Messaging Exception while building calendar message from source MimeMessage", e);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public static MimeMessage createForwardedInviteMessage(MimeMessage mmOrig, String origSenderEmail, String forwarderEmail, String[] forwardTo)
/*      */   {
/*  712 */     List<Address> rcpts = new ArrayList();
/*  713 */     for (String to : forwardTo) {
/*      */       try {
/*  715 */         rcpts.add(new JavaMailInternetAddress(to));
/*      */       } catch (AddressException e) {
/*  717 */         ZimbraLog.calendar.warn("Ignoring invalid address \"" + to + "\" during invite forward");
/*      */       }
/*      */     }
/*  720 */     if (rcpts.isEmpty())
/*  721 */       return null;
/*  722 */     MimeMessage mm = null;
/*      */     try {
/*  724 */       mm = new ZMimeMessage(mmOrig);
/*  725 */       mm.removeHeader("To");
/*  726 */       mm.removeHeader("Cc");
/*  727 */       mm.removeHeader("Bcc");
/*  728 */       mm.addRecipients(Message.RecipientType.TO, (Address[])rcpts.toArray(new Address[0]));
/*      */       
/*  730 */       mm.setReplyTo(new Address[] { new JavaMailInternetAddress(origSenderEmail) });
/*  731 */       mm.removeHeader("Date");
/*  732 */       mm.removeHeader("Message-ID");
/*  733 */       mm.removeHeader("Return-Path");
/*  734 */       mm.removeHeader("Received");
/*      */       
/*      */ 
/*  737 */       mm.setHeader("X-Zimbra-Calendar-Intended-For", forwarderEmail);
/*      */       
/*  739 */       mm.saveChanges();
/*      */     } catch (MessagingException e) {
/*  741 */       ZimbraLog.calendar.warn("Unable to compose email for invite forwarding", e);
/*      */     }
/*  743 */     return mm;
/*      */   }
/*      */   
/*      */   public static MimeMessage createForwardedPrivateInviteMessage(Account account, Locale lc, String method, List<Invite> invites, String origSenderEmail, String forwarderEmail, String[] forwardTo)
/*      */     throws ServiceException
/*      */   {
/*  749 */     if ((invites == null) || (invites.isEmpty()))
/*  750 */       return null;
/*  751 */     List<Address> rcpts = new ArrayList();
/*  752 */     for (String to : forwardTo) {
/*      */       try {
/*  754 */         rcpts.add(new JavaMailInternetAddress(to));
/*      */       } catch (AddressException e) {
/*  756 */         ZimbraLog.calendar.warn("Ignoring invalid address \"" + to + "\" during invite forward");
/*      */       }
/*      */     }
/*  759 */     if (rcpts.isEmpty()) {
/*  760 */       return null;
/*      */     }
/*  762 */     String subject = L10nUtil.getMessage(L10nUtil.MsgKey.calendarSubjectWithheld, lc, new Object[0]);
/*      */     
/*  764 */     List<Invite> filteredInvs = new ArrayList();
/*  765 */     for (Invite inv : invites) {
/*  766 */       Invite filtered = inv.newCopy();
/*  767 */       filtered.clearAlarms();
/*  768 */       filtered.clearPrivateInfo();
/*  769 */       filtered.setName(subject);
/*      */       
/*  771 */       List<ZAttendee> atts = inv.getAttendees();
/*  772 */       if ((atts != null) && (forwarderEmail != null)) {
/*  773 */         for (ZAttendee att : atts) {
/*  774 */           if (forwarderEmail.equalsIgnoreCase(att.getAddress())) {
/*  775 */             filtered.addAttendee(att);
/*      */           }
/*      */         }
/*      */       }
/*  779 */       filteredInvs.add(filtered);
/*      */     }
/*      */     
/*  782 */     MimeMessage mm = null;
/*      */     try {
/*  784 */       mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
/*  785 */       mm.setFrom(new JavaMailInternetAddress(origSenderEmail));
/*  786 */       mm.addRecipients(Message.RecipientType.TO, (Address[])rcpts.toArray(new Address[0]));
/*      */       
/*  788 */       mm.setHeader("X-Zimbra-Calendar-Intended-For", forwarderEmail);
/*  789 */       mm.setSubject(subject);
/*      */       
/*  791 */       StringWriter writer = new StringWriter();
/*      */       try {
/*  793 */         writer.write("BEGIN:VCALENDAR\r\n");
/*      */         
/*  795 */         ZCalendar.ZProperty prop = new ZCalendar.ZProperty(ZCalendar.ICalTok.PRODID, "Zimbra-Calendar-Provider");
/*  796 */         prop.toICalendar(writer);
/*  797 */         prop = new ZCalendar.ZProperty(ZCalendar.ICalTok.VERSION, "2.0");
/*  798 */         prop.toICalendar(writer);
/*  799 */         prop = new ZCalendar.ZProperty(ZCalendar.ICalTok.METHOD, method);
/*  800 */         prop.toICalendar(writer);
/*      */         
/*  802 */         Invite firstInv = (Invite)filteredInvs.get(0);
/*  803 */         TimeZoneMap tzmap = new TimeZoneMap(firstInv.getTimeZoneMap().getLocalTimeZone());
/*  804 */         for (Invite inv : filteredInvs) {
/*  805 */           tzmap.add(inv.getTimeZoneMap());
/*      */         }
/*  807 */         for (Iterator<ICalTimeZone> iter = tzmap.tzIterator(); iter.hasNext();) {
/*  808 */           ICalTimeZone tz = (ICalTimeZone)iter.next();
/*  809 */           tz.newToVTimeZone().toICalendar(writer);
/*      */         }
/*      */         
/*  812 */         for (Invite inv : filteredInvs) {
/*  813 */           ZCalendar.ZComponent comp = inv.newToVComponent(false, true);
/*  814 */           comp.toICalendar(writer);
/*      */         }
/*  816 */         writer.write("END:VCALENDAR\r\n");
/*      */       } catch (IOException e) {
/*  818 */         throw ServiceException.FAILURE("Error writing iCalendar", e);
/*      */       } finally {
/*  820 */         Closeables.closeQuietly(writer);
/*      */       }
/*  822 */       mm.setText(writer.toString());
/*      */       
/*  824 */       ContentType ct = new ContentType("text/calendar");
/*  825 */       ct.setParameter("charset", "utf-8");
/*  826 */       ct.setParameter("method", method);
/*  827 */       mm.setHeader("Content-Type", ct.toString());
/*      */     } catch (MessagingException e) {
/*  829 */       ZimbraLog.calendar.warn("Unable to compose email for invite forwarding", e);
/*      */     }
/*  831 */     return mm;
/*      */   }
/*      */   
/*      */ 
/*      */   private static MimeMessage createCalendarInviteDeniedMessage(Account fromAccount, Account senderAccount, boolean onBehalfOf, boolean allowPrivateAccess, Address toAddr, Invite inv, L10nUtil.MsgKey bodyTextKey)
/*      */     throws ServiceException
/*      */   {
/*  838 */     Locale locale = !onBehalfOf ? fromAccount.getLocale() : senderAccount.getLocale();
/*      */     
/*  840 */     Identity fromIdentity = getTargetedIdentity(fromAccount, inv);
/*  841 */     StringBuilder replyText = new StringBuilder();
/*      */     
/*  843 */     String sigText = getSignatureText(fromAccount, fromIdentity, "zimbraPrefCalendarAutoDenySignatureId");
/*  844 */     if ((sigText == null) || (sigText.length() < 1))
/*  845 */       sigText = L10nUtil.getMessage(bodyTextKey, locale, new Object[0]);
/*  846 */     if ((sigText != null) && (sigText.length() > 0))
/*  847 */       replyText.append(sigText).append("\r\n");
/*  848 */     attachInviteSummary(replyText, inv, null, locale);
/*      */     
/*  850 */     String subject = L10nUtil.getMessage(L10nUtil.MsgKey.calendarReplySubjectDecline, locale, new Object[0]) + ": " + inv.getName();
/*  851 */     String uid = inv.getUid();
/*  852 */     ParsedDateTime exceptDt = null;
/*  853 */     if (inv.hasRecurId())
/*  854 */       exceptDt = inv.getRecurId().getDt();
/*  855 */     Invite replyInv = replyToInvite(fromAccount, senderAccount, onBehalfOf, allowPrivateAccess, inv, VERB_DECLINE, subject, exceptDt);
/*  856 */     ZCalendar.ZVCalendar iCal = replyInv.newToICalendar(true);
/*  857 */     Address fromAddr = fromIdentity.getFriendlyEmailAddress();
/*  858 */     Address senderAddr = null;
/*  859 */     if (onBehalfOf)
/*  860 */       senderAddr = AccountUtil.getFriendlyEmailAddress(senderAccount);
/*  861 */     List<Address> toAddrs = new ArrayList(1);
/*  862 */     toAddrs.add(toAddr);
/*  863 */     return createCalendarMessage(senderAccount, fromAddr, senderAddr, toAddrs, subject, replyText.toString(), null, uid, iCal);
/*      */   }
/*      */   
/*      */ 
/*      */   @VisibleForTesting
/*      */   public static boolean allowInviteAutoDeclinedNotification(Mailbox mbox, Account declinerAcct, String senderEmail, Account senderAccount, boolean applyToCalendar, ZAttendee matchingAttendee)
/*      */     throws ServiceException
/*      */   {
/*  871 */     if (senderEmail == null) {
/*  872 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline - unknown sender");
/*  873 */       return false;
/*      */     }
/*  875 */     if (!applyToCalendar) {
/*  876 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline to %s - no auto-reply when processed as message-only", new Object[] { senderEmail });
/*      */       
/*  878 */       return false;
/*      */     }
/*  880 */     if (declinerAcct.isIsSystemResource()) {
/*  881 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline from %s to %s - because %s is a system resource", new Object[] { declinerAcct.getName(), senderEmail, declinerAcct.getName() });
/*      */       
/*      */ 
/*  884 */       return false;
/*      */     }
/*  886 */     if (!declinerAcct.isPrefCalendarSendInviteDeniedAutoReply()) {
/*  887 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline to=%s - %s=%s", new Object[] { senderEmail, "zimbraPrefCalendarSendInviteDeniedAutoReply", Boolean.valueOf(declinerAcct.isPrefCalendarSendInviteDeniedAutoReply()) });
/*      */       
/*      */ 
/*  890 */       return false;
/*      */     }
/*  892 */     if ((!DebugConfig.calendarEnableInviteDeniedReplyForUnlistedAttendee) && (matchingAttendee == null))
/*      */     {
/*  894 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline to=%s - %s is not a direct attendee", new Object[] { senderEmail, declinerAcct.getName() });
/*      */       
/*  896 */       return false;
/*      */     }
/*  898 */     ZAttrProvisioning.PrefCalendarAllowedTargetsForInviteDeniedAutoReply validTargetSetting = declinerAcct.getPrefCalendarAllowedTargetsForInviteDeniedAutoReply();
/*      */     
/*  900 */     switch (validTargetSetting) {
/*      */     case all: 
/*  902 */       return true;
/*      */     case internal: 
/*  904 */       if (senderAccount == null) {
/*  905 */         ZimbraLog.calendar.info("Suppressed Invite Auto Decline to=%s - not internal", new Object[] { senderEmail });
/*  906 */         return false;
/*      */       }
/*  908 */       return true;
/*      */     }
/*      */     
/*      */     
/*      */ 
/*      */ 
/*  914 */     if (senderAccount == null) {
/*  915 */       ZimbraLog.calendar.info("Suppressed Invite Auto Decline to=%s - no account for sender so not in attendee domain=%s", new Object[] { senderEmail, declinerAcct.getDomainName() });
/*      */       
/*      */ 
/*  918 */       return false;
/*      */     }
/*  920 */     String senderDomain = senderAccount.getDomainName();
/*  921 */     if ((senderDomain != null) && (senderDomain.equalsIgnoreCase(declinerAcct.getDomainName()))) {
/*  922 */       return true;
/*      */     }
/*  924 */     ZimbraLog.calendar.info("Suppressed Invite Auto Decline to=%s - not in attendee domain=%s", new Object[] { senderEmail, declinerAcct.getDomainName() });
/*      */     
/*  926 */     return false;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static void handleInviteAutoDeclinedNotification(OperationContext octxt, Mailbox mbox, Account fromAccount, String senderEmail, Account senderAccount, boolean onBehalfOf, boolean applyToCalendar, int inviteMsgId, Invite invite)
/*      */     throws ServiceException
/*      */   {
/*  934 */     if (allowInviteAutoDeclinedNotification(mbox, fromAccount, senderEmail, senderAccount, applyToCalendar, invite.getMatchingAttendee(fromAccount)))
/*      */     {
/*  936 */       RedoableOp redoPlayer = octxt != null ? octxt.getPlayer() : null;
/*  937 */       RedoLogProvider redoProvider = RedoLogProvider.getInstance();
/*      */       
/*      */ 
/*  940 */       if ((redoProvider.isMaster()) && ((redoPlayer == null) || (redoProvider.getRedoLogManager().getInCrashRecovery())))
/*      */       {
/*  942 */         ItemId origMsgId = new ItemId(mbox, inviteMsgId);
/*  943 */         sendInviteDeniedMessage(octxt, fromAccount, senderAccount, onBehalfOf, true, mbox, origMsgId, senderEmail, invite);
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */   public static void sendInviteDeniedMessage(final OperationContext octxt, Account fromAccount, Account senderAccount, boolean onBehalfOf, boolean allowPrivateAccess, Mailbox mbox, final ItemId origMsgId, String toEmail, Invite inv)
/*      */     throws ServiceException
/*      */   {
/*      */     Address toAddr;
/*      */     
/*      */     try
/*      */     {
/*  956 */       toAddr = new JavaMailInternetAddress(toEmail);
/*      */     } catch (AddressException e) {
/*  958 */       throw ServiceException.FAILURE("Bad address: " + toEmail, e); }
/*      */     L10nUtil.MsgKey bodyTextKey;
/*      */     L10nUtil.MsgKey bodyTextKey;
/*  961 */     if ((fromAccount instanceof CalendarResource)) {
/*  962 */       bodyTextKey = L10nUtil.MsgKey.calendarResourceDefaultReplyPermissionDenied;
/*      */     } else
/*  964 */       bodyTextKey = L10nUtil.MsgKey.calendarUserReplyPermissionDenied;
/*  965 */     final MimeMessage mm = createCalendarInviteDeniedMessage(fromAccount, senderAccount, onBehalfOf, allowPrivateAccess, toAddr, inv, bodyTextKey);
/*      */     
/*      */ 
/*      */ 
/*  969 */     Runnable r = new Runnable()
/*      */     {
/*      */       public void run() {
/*      */         try {
/*  973 */           MailSender mailSender = CalendarMailSender.getCalendarMailSender(this.val$mbox).setSendPartial(true);
/*  974 */           mailSender.sendMimeMessage(octxt, this.val$mbox, Boolean.valueOf(true), mm, null, origMsgId, MailSender.MSGTYPE_REPLY, null, false);
/*      */         } catch (ServiceException e) {
/*  976 */           ZimbraLog.calendar.warn("Ignoring error while sending permission-denied auto reply", e);
/*      */         } catch (OutOfMemoryError e) {
/*  978 */           Zimbra.halt("OutOfMemoryError while sending permission-denied auto reply", e);
/*      */         }
/*      */       }
/*  981 */     };
/*  982 */     Thread senderThread = new Thread(r, "CalendarPermDeniedReplySender");
/*  983 */     senderThread.setDaemon(true);
/*  984 */     senderThread.start();
/*      */   }
/*      */   
/*      */ 
/*      */   public static void sendInviteAutoForwardMessage(final OperationContext octxt, Mailbox mbox, final ItemId origMsgId, final MimeMessage mm)
/*      */   {
/*  990 */     Runnable r = new Runnable()
/*      */     {
/*      */       public void run() {
/*      */         try {
/*  994 */           MailSender sender = CalendarMailSender.getCalendarMailSender(this.val$mbox).setSaveToSent(true).setOriginalMessageId(origMsgId).setReplyType(MailSender.MSGTYPE_REPLY).setSendPartial(true);
/*      */           
/*      */ 
/*  997 */           sender.setRedirectMode(true);
/*  998 */           sender.sendMimeMessage(octxt, this.val$mbox, mm);
/*      */         } catch (ServiceException e) {
/* 1000 */           ZimbraLog.calendar.warn("Ignoring error while sending permission-denied auto reply", e);
/*      */         } catch (OutOfMemoryError e) {
/* 1002 */           Zimbra.halt("OutOfMemoryError while sending permission-denied auto reply", e);
/*      */         }
/*      */       }
/* 1005 */     };
/* 1006 */     Thread senderThread = new Thread(r, "CalendarInviteForwardSender");
/* 1007 */     senderThread.setDaemon(true);
/* 1008 */     senderThread.start();
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static ItemId sendPartial(OperationContext octxt, Mailbox mbox, MimeMessage mm, List<FileUploadServlet.Upload> uploads, ItemId origMsgId, String replyType, String identityId, boolean replyToSender)
/*      */     throws ServiceException
/*      */   {
/* 1016 */     return sendPartial(octxt, mbox, mm, uploads, origMsgId, replyType, identityId, replyToSender, false);
/*      */   }
/*      */   
/*      */   public static ItemId sendPartial(OperationContext octxt, Mailbox mbox, MimeMessage mm, List<FileUploadServlet.Upload> uploads, ItemId origMsgId, String replyType, String identityId, boolean replyToSender, boolean asAdmin) throws ServiceException
/*      */   {
/* 1021 */     ItemId id = null;
/*      */     try {
/* 1023 */       MailSender mailSender = getCalendarMailSender(mbox).setSendPartial(true);
/* 1024 */       if (asAdmin) {
/* 1025 */         mailSender.setSkipHeaderUpdate(true);
/* 1026 */         id = mailSender.sendMimeMessage(octxt, mbox, Boolean.FALSE, mm, uploads, origMsgId, replyType, null, replyToSender);
/*      */       } else {
/* 1028 */         id = mailSender.sendMimeMessage(octxt, mbox, mm, uploads, origMsgId, replyType, identityId, replyToSender);
/*      */       }
/*      */     } catch (MailServiceException e) {
/* 1031 */       if (e.getCode().equals("mail.SEND_PARTIAL_ADDRESS_FAILURE")) {
/* 1032 */         ZimbraLog.calendar.info("Unable to send to some addresses: " + e);
/*      */       } else {
/* 1034 */         throw e;
/*      */       }
/*      */     }
/* 1037 */     return id;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Invite replyToInvite(Account acct, Account authAcct, boolean onBehalfOf, boolean allowPrivateAccess, Invite oldInv, Verb verb, String replySubject, ParsedDateTime exceptDt)
/*      */     throws ServiceException
/*      */   {
/* 1046 */     return replyToInvite(acct, null, authAcct, onBehalfOf, allowPrivateAccess, oldInv, verb, replySubject, exceptDt);
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public static Invite replyToInvite(Account acct, String identityId, Account authAcct, boolean onBehalfOf, boolean allowPrivateAccess, Invite oldInv, Verb verb, String replySubject, ParsedDateTime exceptDt)
/*      */     throws ServiceException
/*      */   {
/* 1075 */     Invite reply = new Invite(oldInv.getItemType(), ZCalendar.ICalTok.REPLY.toString(), new TimeZoneMap(Util.getAccountTimeZone(onBehalfOf ? authAcct : acct)), oldInv.isOrganizer());
/*      */     
/*      */ 
/*      */ 
/*      */ 
/* 1080 */     reply.setLocalOnly(false);
/*      */     
/* 1082 */     reply.getTimeZoneMap().add(oldInv.getTimeZoneMap());
/* 1083 */     reply.setIsAllDayEvent(oldInv.isAllDayEvent());
/*      */     
/* 1085 */     Identity identity = null;
/* 1086 */     if (identityId != null) {
/* 1087 */       identity = acct.getIdentityById(identityId);
/* 1088 */       if (identity == null) {
/* 1089 */         ZimbraLog.calendar.warn("No such identity " + identityId + " for account " + acct.getName());
/* 1090 */         identity = getTargetedIdentity(acct, oldInv);
/*      */       }
/*      */     } else {
/* 1093 */       identity = getTargetedIdentity(acct, oldInv);
/*      */     }
/* 1095 */     String identityAddr = identity.getAttr("zimbraPrefFromAddress");
/* 1096 */     String identityCn = identity.getAttr("zimbraPrefFromDisplay");
/*      */     
/*      */ 
/* 1099 */     ZAttendee meReply = null;
/* 1100 */     ZAttendee me = oldInv.getMatchingAttendee(acct, identityId);
/* 1101 */     if (me != null) {
/* 1102 */       String atAddr = me.getAddress();
/*      */       
/* 1104 */       if (identityAddr.equalsIgnoreCase(atAddr)) {
/* 1105 */         meReply = new ZAttendee(identityAddr);
/* 1106 */         if (identityCn != null)
/* 1107 */           meReply.setCn(identityCn);
/*      */       } else {
/* 1109 */         meReply = new ZAttendee(atAddr);
/* 1110 */         if (me.hasCn())
/* 1111 */           meReply.setCn(me.getCn());
/*      */       }
/* 1113 */       meReply.setPartStat(verb.getXmlPartStat());
/* 1114 */       if (me.hasRole())
/* 1115 */         meReply.setRole(me.getRole());
/* 1116 */       if (me.hasCUType())
/* 1117 */         meReply.setCUType(me.getCUType());
/*      */     } else {
/* 1119 */       meReply = new ZAttendee(identityAddr);
/* 1120 */       meReply.setPartStat(verb.getXmlPartStat());
/* 1121 */       if (identityCn != null)
/* 1122 */         meReply.setCn(identityCn);
/*      */     }
/* 1124 */     if (onBehalfOf)
/* 1125 */       meReply.setSentBy(authAcct.getName());
/* 1126 */     reply.addAttendee(meReply);
/*      */     
/* 1128 */     boolean hidePrivate = (!oldInv.isPublic()) && (!allowPrivateAccess);
/* 1129 */     reply.setClassProp(oldInv.getClassProp());
/*      */     
/*      */ 
/*      */ 
/* 1133 */     reply.setDtStart(oldInv.getStartTime());
/* 1134 */     reply.setDtEnd(oldInv.getEffectiveEndTime());
/* 1135 */     if (!hidePrivate) {
/* 1136 */       reply.setLocation(oldInv.getLocation());
/*      */     } else {
/* 1138 */       reply.setLocation("");
/*      */     }
/*      */     
/* 1141 */     if (oldInv.hasOrganizer()) {
/* 1142 */       reply.setOrganizer(oldInv.getOrganizer());
/*      */     }
/*      */     
/* 1145 */     reply.setUid(oldInv.getUid());
/*      */     
/*      */ 
/* 1148 */     if (exceptDt != null) {
/* 1149 */       reply.setRecurId(new RecurId(exceptDt, RecurId.RANGE_NONE));
/* 1150 */     } else if (oldInv.hasRecurId()) {
/* 1151 */       reply.setRecurId(oldInv.getRecurId());
/* 1152 */     } else if (oldInv.isRecurrence())
/*      */     {
/* 1154 */       reply.setRecurrence((Recurrence.IRecurrence)oldInv.getRecurrence().clone());
/*      */     }
/*      */     
/*      */ 
/* 1158 */     reply.setSeqNo(oldInv.getSeqNo());
/*      */     
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/* 1164 */     Date now = new Date();
/* 1165 */     Date dtStampDate = new Date(oldInv.getDTStamp());
/* 1166 */     if (now.after(dtStampDate)) {
/* 1167 */       dtStampDate = now;
/*      */     }
/* 1169 */     reply.setDtStamp(dtStampDate.getTime());
/*      */     
/*      */ 
/* 1172 */     reply.setName(replySubject);
/*      */     
/*      */ 
/*      */ 
/* 1176 */     return reply;
/*      */   }
/*      */   
/*      */   private static void setCalendarContent(Part part, ZCalendar.ZVCalendar cal) throws MessagingException {
/* 1180 */     String filename = "meeting.ics";
/* 1181 */     part.setDataHandler(new DataHandler(new CalendarDataSource(cal, filename)));
/*      */   }
/*      */   
/*      */   public static MimeBodyPart makeICalIntoMimePart(ZCalendar.ZVCalendar cal) throws ServiceException {
/*      */     try {
/* 1186 */       MimeBodyPart mbp = new ZMimeBodyPart();
/* 1187 */       setCalendarContent(mbp, cal);
/* 1188 */       return mbp;
/*      */     } catch (MessagingException e) {
/* 1190 */       throw ServiceException.FAILURE("Failure creating MimeBodyPart from calendar", e);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   public static MimeMessage createResourceAutoReply(OperationContext octxt, String fromIdentityId, String authIdentityId, Mailbox mbox, Verb verb, boolean partialAccept, String additionalMsgBody, CalendarItem calItem, Invite inv, Invite[] replies, MimeMessage mmInv, boolean addSignature)
/*      */     throws ServiceException
/*      */   {
/* 1200 */     boolean onBehalfOf = false;
/* 1201 */     Account acct = mbox.getAccount();
/* 1202 */     Account authAcct = acct;
/* 1203 */     if (octxt != null) {
/* 1204 */       Account authuser = octxt.getAuthenticatedUser();
/* 1205 */       if (authuser != null) {
/* 1206 */         onBehalfOf = !acct.getId().equalsIgnoreCase(authuser.getId());
/* 1207 */         if (onBehalfOf) {
/* 1208 */           authAcct = authuser;
/*      */         }
/*      */       }
/*      */     }
/* 1212 */     Account organizer = inv.getOrganizerAccount();
/* 1213 */     Locale lc; Locale lc; if (organizer != null) {
/* 1214 */       lc = organizer.getLocale();
/*      */     } else
/* 1216 */       lc = authAcct.getLocale();
/* 1217 */     boolean asAdmin = octxt != null ? octxt.isUsingAdminPrivileges() : false;
/* 1218 */     boolean allowPrivateAccess = calItem.allowPrivateAccess(authAcct, asAdmin);
/* 1219 */     boolean hidePrivate = (!inv.isPublic()) && (!allowPrivateAccess);
/*      */     String subject;
/* 1221 */     String subject; if (hidePrivate) {
/* 1222 */       subject = L10nUtil.getMessage(L10nUtil.MsgKey.calendarSubjectWithheld, lc, new Object[0]);
/*      */     } else
/* 1224 */       subject = inv.getName();
/* 1225 */     String replySubject = getReplySubject(verb, subject, lc);
/*      */     
/*      */ 
/* 1228 */     ZCalendar.ZVCalendar iCal = null;
/* 1229 */     for (Invite replyInv : replies) {
/* 1230 */       if (iCal == null) {
/* 1231 */         iCal = replyInv.newToICalendar(!hidePrivate);
/*      */       } else {
/* 1233 */         ZCalendar.ZComponent cancelComp = replyInv.newToVComponent(true, !hidePrivate);
/* 1234 */         iCal.addComponent(cancelComp);
/*      */       }
/*      */     }
/* 1237 */     return createDefaultReply(acct, fromIdentityId, authAcct, authIdentityId, asAdmin, onBehalfOf, calItem, inv, mmInv, replySubject, verb, partialAccept, additionalMsgBody, iCal, addSignature);
/*      */   }
/*      */   
/*      */   public static MimeMessage createForwardNotifyMessage(Account senderAcct, Account toAcct, String to, Address[] rcpts, Invite inv) throws MessagingException, ServiceException
/*      */   {
/* 1242 */     MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
/* 1243 */     Locale lc = toAcct.getLocale();
/* 1244 */     mm.setSubject(L10nUtil.getMessage(L10nUtil.MsgKey.calendarForwardNotificationSubject, lc, new Object[] { inv.getName() }), "utf-8");
/* 1245 */     mm.setSentDate(new Date());
/* 1246 */     String postmaster = senderAcct.getAttr("zimbraNewMailNotificationFrom");
/* 1247 */     Map<String, String> vars = new HashMap();
/* 1248 */     vars.put("RECIPIENT_DOMAIN", senderAcct.getDomainName());
/* 1249 */     postmaster = StringUtil.fillTemplate(postmaster, vars);
/* 1250 */     mm.setSender(new JavaMailInternetAddress(postmaster));
/* 1251 */     mm.setFrom(new JavaMailInternetAddress(senderAcct.getName()));
/* 1252 */     mm.setRecipient(Message.RecipientType.TO, new JavaMailInternetAddress(to));
/*      */     
/* 1254 */     MimeMultipart mmp = new ZMimeMultipart("alternative");
/* 1255 */     mm.setContent(mmp);
/*      */     
/* 1257 */     String sender = senderAcct.getCn() + " <" + senderAcct.getName() + ">";
/* 1258 */     String time = FriendlyCalendaringDescription.getTimeDisplayString(inv.getStartTime(), inv.getEndTime(), inv.isRecurrence(), inv.isAllDayEvent(), lc, toAcct);
/*      */     
/* 1260 */     StringBuilder sb = new StringBuilder();
/* 1261 */     StringBuilder sbHtml = new StringBuilder();
/* 1262 */     for (Address rcpt : rcpts) {
/* 1263 */       sb.append(rcpt.toString()).append("\n\t");
/* 1264 */       InternetAddress address = new JavaMailInternetAddress(rcpt.toString());
/* 1265 */       sbHtml.append("<a href=\"mailto:").append(address.getAddress()).append("\">");
/* 1266 */       if (address.getPersonal() != null) {
/* 1267 */         sbHtml.append(address.getPersonal()).append("</a>").append("<br>");
/*      */       } else {
/* 1269 */         sbHtml.append(address.getAddress()).append("</a>").append("<br>");
/*      */       }
/*      */     }
/* 1272 */     String recipients = sb.toString();
/* 1273 */     String recipientsHtml = sbHtml.toString();
/* 1274 */     if (inv.isRecurrence()) {
/* 1275 */       ZRecur zr = FriendlyCalendaringDescription.getRecur(inv);
/* 1276 */       time = time + " (" + FriendlyCalendaringDescription.getRecurrenceDisplayString(zr, inv.getStartTime().getCalendarCopy(), lc) + ")";
/*      */     }
/* 1278 */     String text = L10nUtil.getMessage(L10nUtil.MsgKey.calendarForwardNotificationBody, lc, new Object[] { sender, inv.getName(), time, recipients });
/* 1279 */     MimeBodyPart textPart = new ZMimeBodyPart();
/* 1280 */     textPart.setText(text, "utf-8");
/* 1281 */     mmp.addBodyPart(textPart);
/*      */     
/* 1283 */     sender = "<a href=\"mailto:" + senderAcct.getName() + "\">" + senderAcct.getCn() + "</a>";
/* 1284 */     String html = L10nUtil.getMessage(L10nUtil.MsgKey.calendarForwardNotificationBodyHtml, lc, new Object[] { sender, inv.getName(), time, recipientsHtml });
/* 1285 */     MimeBodyPart htmlPart = new ZMimeBodyPart();
/* 1286 */     htmlPart.setContent(html, "text/html; charset=utf-8");
/* 1287 */     mmp.addBodyPart(htmlPart);
/*      */     
/* 1289 */     mm.saveChanges();
/* 1290 */     return mm;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public static void sendResourceAutoReply(final OperationContext octxt, Mailbox mbox, final boolean saveToSent, Verb verb, boolean partialAccept, String additionalMsgBody, CalendarItem calItem, Invite inv, Invite[] replies, MimeMessage mmInv)
/*      */     throws ServiceException
/*      */   {
/* 1298 */     Identity iden = getTargetedIdentity(mbox.getAccount(), inv);
/* 1299 */     final MimeMessage mm = createResourceAutoReply(octxt, iden.getId(), iden.getId(), mbox, verb, partialAccept, additionalMsgBody, calItem, inv, replies, mmInv, true);
/*      */     
/* 1301 */     final String replyType = MailSender.MSGTYPE_REPLY;
/* 1302 */     final int invId = inv.getMailItemId();
/*      */     
/*      */ 
/* 1305 */     Runnable r = new Runnable()
/*      */     {
/*      */       public void run() {
/*      */         try {
/* 1309 */           MailSender mailSender = CalendarMailSender.getCalendarMailSender(this.val$mbox).setSendPartial(true);
/* 1310 */           mailSender.sendMimeMessage(octxt, this.val$mbox, Boolean.valueOf(saveToSent), mm, null, new ItemId(this.val$mbox, invId), replyType, null, false);
/*      */         } catch (ServiceException e) {
/* 1312 */           ZimbraLog.calendar.warn("Ignoring error while sending auto accept/decline reply", e);
/*      */         } catch (OutOfMemoryError e) {
/* 1314 */           Zimbra.halt("OutOfMemoryError while sending calendar resource auto accept/decline reply", e);
/*      */         }
/*      */       }
/* 1317 */     };
/* 1318 */     Thread senderThread = new Thread(r, "CalendarAutoAcceptDeclineReplySender");
/* 1319 */     senderThread.setDaemon(true);
/* 1320 */     senderThread.start();
/*      */   }
/*      */   
/*      */   private static Identity getTargetedIdentity(Account acct, Invite invite)
/*      */     throws ServiceException
/*      */   {
/* 1326 */     ZAttendee addressedAtt = invite.getMatchingAttendee(acct);
/* 1327 */     String addr; if ((addressedAtt != null) && (addressedAtt.getAddress() != null)) {
/* 1328 */       addr = addressedAtt.getAddress();
/* 1329 */       List<Identity> idens = Provisioning.getInstance().getAllIdentities(acct);
/* 1330 */       for (Identity iden : idens) {
/* 1331 */         String idenAddr = iden.getAttr("zimbraPrefFromAddress");
/* 1332 */         if (addr.equalsIgnoreCase(idenAddr)) {
/* 1333 */           return iden;
/*      */         }
/*      */       }
/*      */     }
/* 1337 */     return acct.getDefaultIdentity();
/*      */   }
/*      */   
/*      */   private static String getSignatureText(Account acct, Identity identity, String signatureKey) throws ServiceException {
/* 1341 */     String sigId = identity.getAttr(signatureKey);
/* 1342 */     if (sigId == null)
/* 1343 */       return null;
/* 1344 */     Signature sig = Provisioning.getInstance().get(acct, Key.SignatureBy.id, sigId);
/* 1345 */     if (sig == null) {
/* 1346 */       ZimbraLog.calendar.warn("No such signature " + sigId + " for account " + acct.getName());
/* 1347 */       return null;
/*      */     }
/* 1349 */     String attr = SignatureUtil.mimeTypeToAttrName("text/plain");
/* 1350 */     return sig.getAttr(attr, null);
/*      */   }
/*      */   
/*      */ 
/*      */   private static class HtmlPartDataSource
/*      */     implements DataSource
/*      */   {
/*      */     private static final String CONTENT_TYPE = "text/html; charset=utf-8";
/*      */     
/*      */     private static final String HEAD = "<html><body>\n<pre style=\"font-family: monospace; font-size: 14px\">\n";
/*      */     private static final String TAIL = "</pre>\n</body></html>\n";
/*      */     private static final String NAME = "HtmlDataSource";
/*      */     private String mText;
/* 1363 */     private byte[] mBuf = null;
/*      */     
/*      */     public HtmlPartDataSource(String text) {
/* 1366 */       this.mText = text;
/* 1367 */       this.mText = this.mText.replaceAll("&", "&amp;");
/* 1368 */       this.mText = this.mText.replaceAll("<", "&lt;");
/* 1369 */       this.mText = this.mText.replaceAll(">", "&gt;");
/*      */     }
/*      */     
/*      */     public String getContentType()
/*      */     {
/* 1374 */       return "text/html; charset=utf-8";
/*      */     }
/*      */     
/*      */     public InputStream getInputStream() throws IOException
/*      */     {
/* 1379 */       synchronized (this) {
/* 1380 */         if (this.mBuf == null) {
/* 1381 */           ByteArrayOutputStream buf = new ByteArrayOutputStream();
/* 1382 */           OutputStreamWriter wout = new OutputStreamWriter(buf, "utf-8");
/*      */           
/* 1384 */           String text = "<html><body>\n<pre style=\"font-family: monospace; font-size: 14px\">\n" + this.mText + "</pre>\n</body></html>\n";
/* 1385 */           wout.write(text);
/* 1386 */           wout.flush();
/* 1387 */           this.mBuf = buf.toByteArray();
/*      */         }
/*      */       }
/* 1390 */       ByteArrayInputStream in = new ByteArrayInputStream(this.mBuf);
/* 1391 */       return in;
/*      */     }
/*      */     
/*      */     public String getName()
/*      */     {
/* 1396 */       return "HtmlDataSource";
/*      */     }
/*      */     
/*      */     public OutputStream getOutputStream()
/*      */     {
/* 1401 */       throw new UnsupportedOperationException();
/*      */     }
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/mailbox/calendar/CalendarMailSender.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */